/**
 * 
 */
package neptune.web.client;

import neptune.web.client.controller.HistoryController;
import neptune.web.client.controller.LogInController;
import neptune.web.client.model.DefaultRoles;
import neptune.web.client.services.ApplicationDataProvider;
import neptune.web.client.services.ClusterDataProvider;
import neptune.web.client.view.ClusterView;
import neptune.web.client.view.ConsoleManager;
import neptune.web.client.view.ExperimentSummaryView;
import neptune.web.client.view.ExperimentView;
import neptune.web.client.view.HistoryTokenUtils;
import neptune.web.client.view.LogInView;
import neptune.web.client.view.OperativeView;
import neptune.web.client.view.PerformanceView;
import neptune.web.client.view.SuperView;
import neptune.web.client.view.TaskView;
import neptune.web.client.view.TemplatesSummaryView;
import neptune.web.client.view.UserView;
import neptune.web.client.view.ViewManager;
import neptune.web.client.view.components.AdminMenuBar;
import neptune.web.client.view.components.MessageWidget;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;

/**
 * Entry point dell'applicazione client, contiene anche metodi di utilita' varia
 * per il client
 * 
 * @author Roberto Bifulco [info@robertobifulco.it, robertobifulco.it]
 * 
 */
public class WebInterface implements EntryPoint {

	public void onModuleLoad() {
		// Elimina il pannello di caricamento iniziale
		RootPanel.get("preloading").setVisible(false);

		startClientApplication();
	}

	/**
	 * Metodo chiamato all'avvio dell'applicazione per l'inizializzazione di
	 * tutte le componenti.
	 */
	private void startClientApplication() {

		// Ottiene il gestore delle view che e' creato al caricamento
		// dell'applicazione, prima della chiamata di questo meotodo
		ViewManager viewManager = ViewManager.getViewManager();

		/*
		 * Creazione delle view
		 */
		// LOGIN VIEW
		LogInView login = new LogInView();
		login.setListener(new LogInController());

		// OPERATIVE VIEW
		// Inizialmente viene definita l'admin menu bar per l'operative view, in
		// realta', non e' una indicazione importante, poiche' a login avvenuto,
		// verra' impostata la menuBar opportuna.
		OperativeView operative = new OperativeView(new AdminMenuBar());

		// Registering consoles
		/*
		 * La registrazione delle console permette di avere nel ConsoleManager
		 * un punto di accesso centrale per l'invio di messaggi all'utente.
		 */
		ConsoleManager.addConsole(login);
		ConsoleManager.addConsole(operative);

		// Registrazione delle view al viewManager
		viewManager.addView(login);
		viewManager.addView(operative);
		/*
		 * fine creazione view
		 */

		// La view attiva all'avvio dell'applicazione deve essere la LogInView
		// TODO valutare la possibilita' di selezionare la view in base
		// all'eventuale token presente nell'history
		viewManager.setActiveView(LogInView.DEFAULT_TOKEN);
		// Aggiunge l'historyController per gestire i token definiti dalle view
		History.addHistoryListener(new HistoryController());

		// Include il viewManager nella pagina html
		RootPanel.get("wrapper").add(viewManager);
	}

	/**
	 * Metodo di che viene adoperato per aggiornare tutte le view definite per
	 * l'OperativeView. L'aggiornamento prevede tanto la creazione quanto
	 * l'eliminazione delle view in base all'attuale ruolo ricoperto
	 * dall'utente.
	 */
	public static void updateViewsOfOperativeView() {
		// Recupera l'operativeView
		SuperView operative = (SuperView) ViewManager.getViewManager()
				.getViewByName(OperativeView.DEFAULT_TOKEN);

		// Se l'Utente e' system admin: Aggiunge, se non e' gia' presente, la
		// userView, clusterView e la performanceView  alla operativeView
		if (ApplicationDataProvider.getInstance().getActualUserRole().equals(
				DefaultRoles.SYSTEM_ADMIN)) {

			if (operative.getViewByName(UserView.DEFAULT_TOKEN) == null) {
				HistoryTokenUtils.unregisterViewToken(UserView.DEFAULT_TOKEN);
				UserView usrView = new UserView();
				operative.addView(usrView);
			}

			if (operative.getViewByName(ClusterView.DEFAULT_TOKEN) == null) {
				HistoryTokenUtils
						.unregisterViewToken(ClusterView.DEFAULT_TOKEN);
				ClusterView clusterView = new ClusterView();
				clusterView.setDataProvider(new ClusterDataProvider());
				operative.addView(clusterView);
			}
			
			if (operative.getViewByName(PerformanceView.DEFAULT_TOKEN) == null) {
				HistoryTokenUtils
						.unregisterViewToken(PerformanceView.DEFAULT_TOKEN);
				PerformanceView performanceView = new PerformanceView();
				//clusterView.setDataProvider(new ClusterDataProvider());
				operative.addView(performanceView);
			}
			
			if (operative.getViewByName(TaskView.DEFAULT_TOKEN) == null) {
				HistoryTokenUtils.unregisterViewToken(TaskView.DEFAULT_TOKEN);
				TaskView taskView  = new TaskView();
				operative.addView( taskView );
			}
			
			if (operative.getViewByName(TemplatesSummaryView.DEFAULT_TOKEN) == null) {
				HistoryTokenUtils.unregisterViewToken(TemplatesSummaryView.DEFAULT_TOKEN);
				TemplatesSummaryView templatesView  = new TemplatesSummaryView();
				operative.addView( templatesView );
			}
		}

		// Se l'Utente e' user: Elimina, se e' presente, la
		// userView dalla operativeView
		if (!ApplicationDataProvider.getInstance().getActualUserRole().equals(
				DefaultRoles.SYSTEM_ADMIN)) {
			operative.removeView(UserView.DEFAULT_TOKEN);
		}

		if (operative.getViewByName(ExperimentSummaryView.DEFAULT_TOKEN) == null) {
			ExperimentSummaryView expSumView = new ExperimentSummaryView();
			operative.addView(expSumView);
		}

		if (operative.getViewByName(ExperimentView.DEFAULT_TOKEN) == null) {
			ExperimentView expView = new ExperimentView();
			operative.addView(expView);
		}
	}

	/**
	 * Mostra una message dialog con il messaggio rappresentato da un
	 * MessageWidget. La dialog puo' essere sia impostata come AutoHide, nel
	 * qual caso scomparira' quando si clicca al di fuori di essa, oppure puo'
	 * essere fatta scomparire manualmente. Per questa ragione, il metodo
	 * restituisce un riferimento alla dialog creata.
	 * 
	 * @param message
	 * @param autohide
	 * @return
	 */
	public static PopupPanel showMessageDialog(Widget message, boolean autohide) {
		PopupPanel popup = new DialogBox(autohide, true);
		popup.add(message);
		popup.setAnimationEnabled(true);
		popup.setStylePrimaryName("MessageDialog");
		popup.center();

		return popup;
	}

	/**
	 * Metodo di utilita' per aggiungere un messaggio al console manager ed allo
	 * stesso tempo mostrare una dialog con l'opzione di AutoHide che conterra'
	 * lo stesso messaggio.
	 * 
	 * @param message
	 * @param error
	 */
	public static void addMessageToConsoleAndShowDialog(String message,
			boolean error) {
		ConsoleManager.addConsoleMessage(message, error);
		showMessageDialog(new MessageWidget(error ? MessageWidget.ERROR
				: MessageWidget.MESSAGE, message), true);
	}
}
